package com.imooc.ecommerce.transactional;

import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;

/**
 * <p>事务失效的场景
 *
 * @author Yaxi.Zhang
 * @since 2022/11/16 17:24
 */
@Slf4j
@Service
public class TransactionalLose {
    /**
     * springboot_user dao
     */
    private final SpringBootUserRepository springBootUserRepository;
    private final AnotherTransactional anotherTransactional;

    public TransactionalLose(SpringBootUserRepository springBootUserRepository, AnotherTransactional anotherTransactional) {
        this.springBootUserRepository = springBootUserRepository;
        this.anotherTransactional = anotherTransactional;
    }

    /**
     * `@Transactional` 默认捕获runtime异常，不会捕获check异常，需要手动指定
     */
    // @Transactional
    @Transactional(rollbackFor = Exception.class)
    public void wrongRollbackFor() throws Exception {
        JpaSpringBootUser springBootUser = new JpaSpringBootUser();
        springBootUser.setUsername("ImoocQinyi-2021-01-01");
        springBootUserRepository.save(springBootUser);

        // ....
        // 由于某种原因抛出了异常
        throw new IOException("throw io exception for check rollback");
    }

    /**
     * <p>同一个类中的方法调用，会导致事务失效
     */
    public void wrongInnerCall() throws Exception {
        this.wrongRollbackFor();
    }

    /**
     * <p>调用其他类的方法，事务不会失效
     */
    public void rightCall() throws Exception {
        anotherTransactional.rightCall();
    }


    @Transactional(rollbackFor = Exception.class)
    public void wrongTryCatch() {
        try {
            JpaSpringBootUser springBootUser = new JpaSpringBootUser();
            springBootUser.setUsername("ImoocQinyi-2021-01-01");
            springBootUserRepository.save(springBootUser);

            // ....
            // 由于某种原因抛出了异常
            throw new IOException("throw io exception for check rollback");
        } catch (Exception ex) {
            log.error("has some error: [{}]", ex.getMessage(), ex);
        }
    }

}
